package com.feidee.data.report.service.crontask;

import com.feidee.data.report.constant.Constant;
import com.feidee.data.report.dao.IHiveDao;
import com.feidee.data.report.dao.IImpalaDao;
import com.feidee.data.report.dao.IMysqlDao;
import com.feidee.data.report.dao.IReportMetadataOpr;
import com.feidee.data.report.dao.IReportAndSourceStatusDao;
import com.feidee.data.report.dao.ISparkDao;
import com.feidee.data.report.util.ToolUtils;
import com.feidee.data.report.util.quartz.QuartzUtil;
import com.feidee.fdcommon.configuration.CustomConfiguration;
import org.apache.log4j.Logger;
import org.quartz.JobKey;

import java.util.HashMap;
import java.util.Map;

public class InitCronJobUtil {

	private IReportMetadataOpr reportMetadataOpr;
	private IHiveDao hiveDao;
	private IImpalaDao impalaDao;
	private IMysqlDao mysqlDao;
	private ISparkDao sparkDao;
	private IReportAndSourceStatusDao reportAndSourceStatusDao;

	private Logger logger = Logger.getLogger(InitCronJobUtil.class);

	/**
	 * 从报表配置库中拿出所有的定时任务,封装为CronReportJob,提交到schduler中
	 */
	public void init() {
		logger.info("********************* 报表定时初始化 ***********************");
		String allFrequencyStr = CustomConfiguration.getString(Constant.ALL_FREQUENCY);
		if (!ToolUtils.isNotNull(allFrequencyStr)) {
			return;
		}
		logger.info("**** 报表配置库中更新频率列表: " + allFrequencyStr);
		String[] frequencyArr = allFrequencyStr.split(Constant.FREQUENCY_SPLIT_FLAG, -1);
		for (String frequencyStr : frequencyArr) {
			// 当前对于每天运行一次的不做处理,仍保持以前crontab调用方式,其他则由Quartz的schduler进行调度
			//当前仅仅针对更新频率为'7'的
			//后续如果每天更新一次也改为依赖Quartz调用,则注释掉下面的if语句块即可
			if ("7".equalsIgnoreCase(frequencyStr)) {
				logger.info("报表初始化: 更新频率'7'每天执行一次, 不依赖Quartz调度...");
				continue;
			}

			String cronExpressStr = CustomConfiguration.getString(frequencyStr);
			if (!ToolUtils.isNotNull(cronExpressStr)) {
				continue;
			}
			// 定时更新Job对象
			CronReportJob cronReportJob = new CronReportJob(cronExpressStr);
			Map<String, Object> metadataMap = new HashMap<String, Object>();
			metadataMap.put("frequency", frequencyStr);
			metadataMap.put("hivedao", hiveDao);
			metadataMap.put("impaladao", impalaDao);
			metadataMap.put("mysqldao", mysqlDao);
			metadataMap.put("sparkDao", sparkDao);
			metadataMap.put("metahandler", reportMetadataOpr);
			metadataMap.put("runstatushandler", reportAndSourceStatusDao);
			logger.info("**** 添加定时更新Job对象: " + cronReportJob.toString() + " ## " + metadataMap + "## cronExpress: "
					+ cronExpressStr);
			/**
			 * todo 2019/12/26 由于当前的定时执行改用azakaban进行调度，故将该方式移除
			 */
			// QuartzUtil.addJob(cronReportJob, metadataMap);
			// 更新Job List
			JobKey jobKey = JobKey.jobKey(cronReportJob.getJobName(), cronReportJob.getGroupName());
			if (!Constant.CurQuartzJobList.contains(jobKey)) {
				Constant.CurQuartzJobList.add(jobKey);
			}
		}
		logger.info("**** 当前所有定时任务: " + Constant.CurQuartzJobList);
		logger.info("************************************************************");
	}

	/**
	 * 退出时关闭定时调度schduler
	 */
	public void close() {
		logger.info("********************* 报表定时结束,清理操作 ***********************");
		QuartzUtil.deleteJobList(Constant.CurQuartzJobList);
		QuartzUtil.shutDownJobs();
		logger.info("*******************************************************************");
	}

	public IReportMetadataOpr getReportMetadataOpr() {
		return reportMetadataOpr;
	}

	public void setReportMetadataOpr(IReportMetadataOpr reportMetadataOpr) {
		this.reportMetadataOpr = reportMetadataOpr;
	}

	public IHiveDao getHiveDao() {
		return hiveDao;
	}

	public void setHiveDao(IHiveDao hiveDao) {
		this.hiveDao = hiveDao;
	}

	public IImpalaDao getImpalaDao() {
		return impalaDao;
	}

	public void setImpalaDao(IImpalaDao impalaDao) {
		this.impalaDao = impalaDao;
	}

	public IMysqlDao getMysqlDao() {
		return mysqlDao;
	}

	public void setMysqlDao(IMysqlDao mysqlDao) {
		this.mysqlDao = mysqlDao;
	}

	public ISparkDao getSparkDao() {
		return sparkDao;
	}

	public void setSparkDao(ISparkDao sparkDao) {
		this.sparkDao = sparkDao;
	}

	public IReportAndSourceStatusDao getReportAndSourceStatusDao() {
		return reportAndSourceStatusDao;
	}

	public void setReportAndSourceStatusDao(IReportAndSourceStatusDao reportAndSourceStatusDao) {
		this.reportAndSourceStatusDao = reportAndSourceStatusDao;
	}

}
